//
//  HRVChartDataModel.swift
//  DaRings
//
//  Created by 尹琼 on 2023/2/18.
//

import UIKit

open class HRVChartDataModel: NSObject {
    
    
    /// 日期
    public var date: Date
    
    /// 是否正在测量
    public var isMeasure: Bool = false
    
    /// 平均数
    public var hrvAvg: Int = 0
    
    /// 图表最大值
    public var chartMaxData: Int = 400
    
    /// 图表最小值
    public var chartMinData: Int = 0
    
    /// 图表Y轴线个数（不包含 0轴线）
    public var chartYAxisCount: Int = 4
     
   
    public var hasData = false
    
    public var chartDatas: [HeartBarData] = []
    
    open var heartRateTitle: String {
        
        return hrvAvg.normalTitle
    }
    
    public init(date: Date, hrvModel: HRVModel) {
        self.date = date
        super.init()
        
        let chartDatas: [HeartBarData] = hrvModel.hrvs.map { hrv in
          
            let dataValue = HeartBarDataValue(high: Double(hrv), low: Double(hrv))
            let barData = HeartBarData(dayTime: dataValue, sleeping: .zero, workouts: .zero, startTime: 0, endTime: 0, avg: hrv)
            
            return barData
        }
        
        let chartTuple = self.calculationYAxisValues(factsMax: hrvModel.max, factsMin: hrvModel.min)
        
        self.hrvAvg = hrvModel.avg
        self.chartDatas = chartDatas
        self.chartMaxData = chartTuple.YAxisMax
        self.chartMinData = chartTuple.YAxisMin
        self.chartYAxisCount = chartTuple.YAxisCount
        
        self.hasData = hrvModel.max > 0
        

    }
    
    public init(date: Date, hrvModels: [HRVModel]) {
        
        self.date = date
        
        super.init()
        
        var dataSource: [HeartBarData] = []
        
        var all: [Int] = []
        var maxValue: Int = 0
        var minValue: Int = 1500
        
        for hrvModel in hrvModels {
            
            // 一天的心率最大最小值平均值
            let dataValue = HeartBarDataValue(high: Double(hrvModel.max), low: Double(hrvModel.min))
            let barData = HeartBarData(dayTime: dataValue, sleeping: .zero, workouts: .zero, startTime: 0, endTime: 0, avg: hrvModel.avg)
            dataSource.append(barData)
            
            maxValue = Swift.max(maxValue, hrvModel.max)
            if hrvModel.min > 0 {
                minValue = Swift.min(minValue, hrvModel.min)
            }
           
            let adayHRVs = hrvModel.hrvs.filter { $0 > 0 }
            
           
            all.append(contentsOf: adayHRVs)
            
            
        }
        var avg = 0
        if !all.isEmpty {
            avg = all.reduce(0, {$0 + $1})/all.count
        }
        if minValue > maxValue {
            minValue = maxValue
        }
        
        let chartTuple = self.calculationYAxisValues(factsMax: maxValue, factsMin: minValue)
        
        self.hrvAvg = avg
        self.chartMaxData = chartTuple.YAxisMax
        self.chartMinData = chartTuple.YAxisMin
        self.chartYAxisCount = chartTuple.YAxisCount
        
        self.chartDatas = dataSource
        self.hasData = hrvAvg > 0
    }

}

public extension HRVChartDataModel {
    
    
    /// 计算图表最大最小值设定
    /// - Parameter factsMax: 实际最大值
    /// - Returns: 元组（图表最大值，图表最小值， y轴线个数）
    func calculationYAxisValues(factsMax: Int, factsMin: Int) ->(YAxisMax: Int, YAxisMin: Int, YAxisCount: Int) {
        
        var max = factsMax
        var min = factsMin
        var count = 4
    
        if max < 190 {
            max = 200
            min = 0
        } else {
            let spcae = 100
            count = 4
            let yu = max%spcae
            var addCount = 1
            if (spcae - yu) < 10 {
               addCount = 2
            }
            max = max - yu + addCount * spcae
            if min < spcae {
                min = 0
            } else {
                
                let yu = min%spcae
                var reductionCount = 0
                
                if (spcae - yu) < 10 {
                    reductionCount = 1
                }
                min = min - yu - reductionCount * spcae
            }
        }
        
        return (max, min, count)
        
    }
    
}
